#include "units.h"
#include "init.h"
#include "rules.h"
#include "players.h"
#include "gui.h"
#include <queue>
#include <string>
#include <sstream>
#include <iostream>



void firstaidkit::effect( unit* u )
{
	u->set_health( u->get_health() + 50 );
	mapa::get_instance()->set_object( 0, this->get_x(), this->get_y() );
	delete this;
};



string unit::get_info()
{
	std::ostringstream st;
	st << "Price: " << price << "  Range: " << range << "  Health: " << health << "  Shield: " << shield << "  Weapon: " << weapon << "  Cost move: " << cost_move << "  Cost_fire: " << cost_fire;
	return st.str();
};



bool unit::move( unsigned int x, unsigned int y )
{
	std::queue< std::pair< unsigned int, unsigned int > >* path = new std::queue< std::pair< unsigned int, unsigned int > >;
	return move_handle( path, x, y );
};



bool unit::move_handle( std::queue< std::pair< unsigned int, unsigned int > >* path, unsigned int x, unsigned int y )
{
	pre_move_info* pmi = new pre_move_info( this, x, y );
	int d = test_move( path, this, x, y );
	if ( d != -1 )
	{	
		pmi->path = path;
		pl->set_time( pl->get_time() - d );
		bonus* b = dynamic_cast< bonus* >( mapa::get_instance()->get_object( x, y ) );
		if ( b!= 0 )
		{
			b->effect( this );
		}
		mapa::get_instance()->set_object( 0, pos_x, pos_y );
		set_pos( x, y );
		mapa::get_instance()->set_object( this, x, y );
		game_gui::get_instance()->show_move( this, x, y, pmi );
		return true;
	}
	else
	{
		return false;
	}
}



void unit::hit( unsigned int w )
{
	int x = ( int )w - ( int )shield;
	if ( x > 0 )
		health -= x;
	else
		health -= 1;
	if ( health <= 0 )
	{
		mapa::get_instance()->set_object( 0, pos_x, pos_y );
		for ( vector< unit* >::iterator it = this->get_player()->units.begin(); it != this->get_player()->units.end(); ++it )
		{
			if ( *it == this )
			{
				this->get_player()->units.erase( it );
				break;
			}
		}
		delete this;
	}
};



bool unit::fire( unsigned int x, unsigned int y )
{
	return fire_handle( x, y );
};



bool unit::fire_handle( unsigned int x, unsigned int y )
{
	pre_fire_info* pfi = new pre_fire_info( this, x, y );
	if ( test_fire( this, x, y ) )
	{
		unit* u;	
		if ( ( u = dynamic_cast< unit* >( mapa::get_instance()->get_object( x, y ) ) ) != 0 )
		{
			pl->set_time( pl->get_time() - ( int )cost_fire );
			u->hit( weapon );
			game_gui::get_instance()->show_fire( this, x, y, pfi );
			game::get_instance()->test_game_end();
			return true;
		}
		else
		{
			return false;
		}

	}
	else
	{
		return false;
	}
};



int unit::get_id()
{
	for ( unsigned int i = 0; i < this->get_player()->units.size(); ++i )
	{
		if ( this->get_player()->units[ i ] == this )
			return i;
	}
	return -1;
};



prototypes* prototypes::get_instance()
{
	static prototypes inst( 0 );
	return &inst;
};